﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Web.Mvc;

namespace MvcContrib.Shp.UI.Menu
{
    public class MenuItemBuilder
    {
        public MenuItemBuilder(MenuItem menuItem, ViewContext viewContext, MenuSettings settings)
        {
            ViewContext = viewContext;
            MenuSettings = settings;
            Items = menuItem.MenuItems;
        }

        protected ViewContext ViewContext { get; private set; }
        protected MenuSettings MenuSettings { get; private set; }

        public List<MenuItem> Items { get; private set; }


        #region Link Menu Methods
        public MenuItem Link(string text)
        {
            return Link(text, null);
        }

        /// <summary>
        /// Adds an item that is a direct link instead of being built off of an action. Used links outside your site.
        /// </summary>
        /// <param name="text">The text displayed for the menu item.</param>
        /// <param name="url">The location to visit</param>
        /// <returns>The menu item to be added to the list</returns>
        public MenuItem Link(string text, string url)
        {
            return Link(text, url, null);
        }

        public MenuItem Link(string text, string url, string iconUrl)
        {
            var item = new MenuItem(ViewContext, MenuSettings) { Text = text, Url = url, IconUrl = iconUrl };
            Items.Add(item);
            return item;
        }
        #endregion Link Menu Methods

        #region Controller Action Link Methods
        /// <summary>
        /// Adds an item. A title will be build out of the action name.
        /// </summary>
        /// <typeparam name="T">The controller that this action is in</typeparam>
        /// <param name="menuAction">The action that this menu should invoke</param>
        /// <returns>The menu item to be added to the list</returns>
        public MenuItem Action<T>(Expression<Action<T>> menuAction) where T : Controller
        {
            return Action(menuAction, null);
        }

        /// <summary>
        /// Adds an item. A title will be build out of the action name.
        /// </summary>
        /// <typeparam name="T">The controller that this action is in</typeparam>
        /// <param name="menuAction">The action that this menu should invoke</param>
        /// <param name="text">The text for this menu item</param>
        /// <returns>The menu item to be added to the list</returns>
        public MenuItem Action<T>(Expression<Action<T>> menuAction, string text) where T : Controller
        {
            return Action(menuAction, text, null);
        }

        public MenuItem Action<T>(Expression<Action<T>> menuAction, string text, string iconUrl) where T : Controller
        {
            var item = new ActionMenuItem<T>(ViewContext, MenuSettings) { MenuAction = menuAction, Text = text, IconUrl = iconUrl };
            Items.Add(item);
            return item;
        }

        public MenuItem Secure<T>(Expression<Action<T>> menuAction) where T : Controller
        {
            return Secure(menuAction, null, null);
        }

        public MenuItem Secure<T>(Expression<Action<T>> menuAction, string text) where T : Controller
        {
            return Secure(menuAction, text, null);
        }

        public MenuItem Secure<T>(Expression<Action<T>> menuAction, string text, string iconUrl) where T : Controller
        {
            var item = new SecureActionMenuItem<T>(ViewContext, MenuSettings)
                           {MenuAction = menuAction, Text = text, IconUrl = iconUrl};
            Items.Add(item);
            return item;
        }
        #endregion Controller Action Link Methods

        #region Content Menu Methods
        public TemplateMenuItem Content(Func<object, object> template)
        {
            var item = new TemplateMenuItem(ViewContext, MenuSettings) { ItemTemplate = template };
            Items.Add(item);
            return item;

            //var item = new MenuItem(ViewContext) { ItemTemplate = template };
            //Items.Add(item);
            //return item;
        }
        #endregion Content Menu Methods
    }
}

//[EditorBrowsable(EditorBrowsableState.Never)] //hide from intellisense in fluent interface
